package controller

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"golang.org/x/net/websocket"
	"net/http"
	"sync"
	"zxs-talks/util"
)

var m map[string]*websocket.Conn
var l sync.Mutex

type Msg struct {
	//type分为几种：
	//init:初始化，生成ID，保存ID-CONN对应，返回ID
	//list:获取ID列表，选择发送对象
	//talk:获取接收ID，获取conn，发送消息
	Type string `json:"type"`
	Msg  string `json:"msg"`
}

type TalkMsg struct {
	To  string `json:"to"`
	Msg string `json:"msg"`
}

func init() {
	m = make(map[string]*websocket.Conn)
}

func Start() {
	r := gin.New()
	r.Static("static", "view")
	r.LoadHTMLGlob("view/html/**")

	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})

	go func() {
		http.Handle("/talk", websocket.Handler(Talk))
		err := http.ListenAndServe(":9999", nil)
		if err != nil {
			panic(err)
		}
	}()
	r.Run()
}

func Talk(conn *websocket.Conn) {
	var err error
	for {
		var msg Msg
		if err = websocket.JSON.Receive(conn, &msg); err != nil {
			conn.Close()
			fmt.Println(err)
			break
		}
		fmt.Println(msg)
		switch msg.Type {
		case "init":
			id := string(util.RandHex(32))
			mapadd(id, conn)
			m1 := map[string]string{"selfid": id}
			bs, _ := json.Marshal(m1)
			err = websocket.Message.Send(conn, string(bs))
		case "list":
			ids := mapkeys()
			m1 := map[string]interface{}{"idlist": ids}
			bs, _ := json.Marshal(m1)
			err = websocket.Message.Send(conn, string(bs))
		case "talk":
			var tm TalkMsg
			err = json.Unmarshal([]byte(msg.Msg), &tm)
			if err != nil {
				conn.Close()
				break
			}
			toc := mapget(tm.To)
			m1 := TalkMsg{tm.To, tm.Msg}
			bs, _ := json.Marshal(m1)
			err = websocket.Message.Send(toc, string(bs))
		}
		fmt.Println(err)
	}
}

func mapdel(c *websocket.Conn) {

}

func mapget(id string) *websocket.Conn {
	l.Lock()
	defer l.Unlock()
	return m[id]
}

func mapadd(id string, conn *websocket.Conn) {
	l.Lock()
	defer l.Unlock()
	for _, o := range m {
		m1 := map[string]string{"newid": id}
		bs, _ := json.Marshal(m1)
		err := websocket.Message.Send(o, string(bs))
		fmt.Println(err)
	}
	m[id] = conn

}

func mapkeys() []string {
	l.Lock()
	defer l.Unlock()
	var ss = make([]string, 0, 0)
	for k, _ := range m {
		ss = append(ss, k)
	}
	return ss
}
